using FireStarterModeller.BO;
using Habanero.BO;
using Habanero.Util;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{
    [TestFixture]
    public class TestDMClass : TestBase
    {
        [SetUp]
        public override void SetupTest()
        {
            //Runs every time that any testmethod is executed
            base.SetupTest();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
        }

        [TearDown]
        public override void TearDownTest()
        {
            //runs every time any testmethod is complete
            base.TearDownTest();
        }

        [Test]
        public void Test_ToString()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtils.CreateUnsavedValidDMClass();

            //---------------Assert Precondition----------------
            string toString = dmClass.ToString();
            //---------------Execute Test ----------------------
            Assert.AreEqual(dmClass.ClassNameBO, toString);
            //---------------Test Result -----------------------

        }

        [Test]
        public void Test_InsertNewDMClass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtils.CreateUnsavedValidDMClass();

            //---------------Assert Precondition----------------
            Assert.IsTrue(dmClass.Status.IsNew);

            //---------------Execute Test ----------------------
            dmClass.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(dmClass.Status.IsNew);
        }

        [Test]
        public void Test_InsertNewDMClass_Invalid()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = new DMClass();

            //---------------Assert Precondition----------------
            Assert.IsTrue(dmClass.Status.IsNew);

            //---------------Execute Test ----------------------
            try
            {
                dmClass.Save();
                Assert.Fail("expected Err");
            }
            //---------------Test Result -----------------------
            catch (BusObjectInAnInvalidStateException ex)
            {
                StringAssert.Contains("Assembly' is a compulsory field and has no value", ex.Message);
                StringAssert.Contains("Mapped Table Name' is a compulsory field and has no value", ex.Message);
                StringAssert.Contains("Class Name BO' is a compulsory field and has no value", ex.Message);
                StringAssert.Contains("Solution ID' is a compulsory field and has no value", ex.Message);
            }
            Assert.IsTrue(dmClass.Status.IsNew);
        }

        [Test]
        public void Test_DeleteDMClass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtils.CreateSavedDMClass();

            //---------------Assert Precondition----------------
            Assert.IsFalse(dmClass.Status.IsNew);
            string message;
            Assert.IsTrue(dmClass.IsDeletable(out message));

            //---------------Execute Test ----------------------
            dmClass.MarkForDelete();
            dmClass.Save();

            //---------------Test Result -----------------------  
            Assert.IsTrue(dmClass.Status.IsNew);
            Assert.IsTrue(dmClass.Status.IsDeleted);
        }

        [Test]
        public void Test_UpdateDMClass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtils.CreateSavedDMClass();

            //---------------Assert Precondition----------------
            Assert.IsFalse(dmClass.Status.IsNew);
            string message;
            Assert.IsTrue(dmClass.IsEditable(out message));

            //---------------Execute Test ----------------------
            dmClass.ClassNameBO = TestUtils.GetRandomString(100, 10000);
            dmClass.MappedTableName = TestUtils.GetRandomString();
            dmClass.DisplayName = TestUtils.GetRandomString();
            dmClass.Assembly = TestUtils.CreateSavedProjectAssemblyInfo();
            dmClass.Generated = true;

            dmClass.Save();

            //---------------Test Result -----------------------
            Assert.IsFalse(dmClass.Status.IsNew);
        }

        [Test]
        public void Test_LoadDMClass()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtils.CreateSavedDMClass();
            BusinessObjectManager.Instance.ClearLoadedObjects();

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            DMClass loadedDMClass = Broker.GetBusinessObject<DMClass>(dmClass.ID);

            //---------------Test Result -----------------------  
            Assert.IsFalse(loadedDMClass.Status.IsNew);
            Assert.AreEqual(loadedDMClass.ID, dmClass.ID);
            //TODO: When not using memory db Assert.AreNotSame(loadedDMClass, dmClass);
        }

        [Test]
        public void Test_CreateBusinessObjectProperty()
        {
            //---------------Set up test pack-------------------
            //BusinessObjectLoaderInMemory businessObjectLoader = (BusinessObjectLoaderInMemory) BORegistry.DataAccessor.BusinessObjectLoader;
            DMSolution dmSolution = TestUtils.CreateSavedDMSolution();
            //Assert.AreEqual(1, businessObjectLoader.GetMemoryDatabase().Count);
            DMClass dmClass = dmSolution.Classes.CreateBusinessObject();
            //Assert.AreEqual(1, businessObjectLoader.GetMemoryDatabase().Count);
            TestUtils.UpdateBusinessObjectWithValidData(dmClass);
            dmClass.Save();
            DMProperty dmProperty =
                dmClass.Properties.CreateBusinessObject();
            TestUtils.UpdateDMClassPropertyWithValidData(dmProperty);
            
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dmSolution.Classes.CreatedBusinessObjects.Count);
            Assert.AreEqual(1, dmSolution.Classes.Count);
            Assert.AreEqual(1, dmClass.Properties.Count);
            Assert.AreEqual(1, dmClass.Properties.CreatedBusinessObjects.Count);
            
            //Assert.AreEqual(1, businessObjectLoader.GetMemoryDatabase().Count);
            //---------------Execute Test ----------------------
            dmProperty.Save();
       
            //---------------Test Result -----------------------
            //Assert.AreEqual(2, businessObjectLoader.GetMemoryDatabase().Count);

            Assert.AreEqual(0, dmClass.Properties.CreatedBusinessObjects.Count);
            Assert.AreEqual(1, dmClass.Properties.Count);
        }

        [Test]
        public void Test_GetProperties()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = TestUtils.CreateSavedDMSolution();
            DMClass dmClass = TestUtils.CreateSavedDMClass(dmSolution);
            DMProperty dmProperty = TestUtils.CreateSavedDMProperty(dmClass);
            
            BusinessObjectManager.Instance.ClearLoadedObjects();
            
            //---------------Assert Precondition----------------
            Assert.IsFalse(dmClass.Status.IsNew);
            Assert.AreEqual(1, dmSolution.Classes.Count);
            Assert.AreEqual(1, dmClass.Properties.Count);

            //---------------Execute Test ----------------------
            DMProperty loadedDMProperty = dmClass.Properties[0];

            //---------------Test Result -----------------------
            Assert.AreEqual(dmProperty.ID, loadedDMProperty.ID);

        }

        [Test]
        public void Test_CreatePrimaryKey()
        {
            //---------------Set up test pack-------------------
            //BusinessObjectLoaderInMemory businessObjectLoader = (BusinessObjectLoaderInMemory) BORegistry.DataAccessor.BusinessObjectLoader;
            //Assert.AreEqual(1, businessObjectLoader.GetMemoryDatabase().Count);
            DMClass dmClass = TestUtils.CreateSavedDMClass();
            //Assert.AreEqual(1, businessObjectLoader.GetMemoryDatabase().Count);
            
            //---------------Assert Precondition----------------
            Assert.AreEqual(null,dmClass.ObjectIdentity);
            //Assert.AreEqual(1, businessObjectLoader.GetMemoryDatabase().Count);
            //---------------Execute Test ----------------------
            DMObjectIdentity primaryKey = TestUtils.CreateSavedObjectIdentityInfo(dmClass);
            //---------------Test Result -----------------------
            //Assert.AreEqual(2, businessObjectLoader.GetMemoryDatabase().Count);
            Assert.AreEqual(primaryKey, dmClass.ObjectIdentity);
        }

        [Test]
        public void Test_SetSuperClass()
        {
            //---------------Set up test pack-------------------
            //BusinessObjectLoaderInMemory businessObjectLoader = (BusinessObjectLoaderInMemory) BORegistry.DataAccessor.BusinessObjectLoader;
            DMSolution dmSolution = TestUtils.CreateSavedDMSolution();
            //Assert.AreEqual(1, businessObjectLoader.GetMemoryDatabase().Count);
            DMClass dmClass = dmSolution.Classes.CreateBusinessObject();
            //Assert.AreEqual(1, businessObjectLoader.GetMemoryDatabase().Count);
            TestUtils.UpdateBusinessObjectWithValidData(dmClass);
            DMSuperClass dmSuperClass = TestUtils.CreateUnsavedValidSuperClassInfo();
            dmSuperClass.Save();
            //---------------Assert Precondition----------------
            Assert.AreEqual(null, dmClass.SuperClass);
            //---------------Execute Test ----------------------

            dmClass.SuperClass = dmSuperClass;
            dmClass.Save();
            //---------------Test Result -----------------------
            //Assert.AreEqual(2, businessObjectLoader.GetMemoryDatabase().Count);
            Assert.AreEqual(dmSuperClass, dmClass.SuperClass);

        }

        [Test]
        public void TestLink_BusinessObjectNameToMappedTableName()
        {
            //---------------Set up test pack-------------------
            DMClass newBO = new DMClass();
            //---------------Execute Test ----------------------
            const string testautocomplete = "TestAutoComplete";
            newBO.ClassNameBO = testautocomplete;
            //---------------Test Result -----------------------
            Assert.AreEqual(testautocomplete, newBO.MappedTableName);
        }

        [Test]
        public void TestLink_BusinessObjectNameToDisplayName_CamelCased()
        {
            //---------------Set up test pack-------------------
            DMClass newBO = new DMClass();
            //---------------Execute Test ----------------------
            const string testautocomplete = "TestAutoComplete";
            newBO.ClassNameBO = testautocomplete;
            //---------------Test Result -----------------------
            Assert.AreEqual(StringUtilities.DelimitPascalCase(testautocomplete, " "), newBO.DisplayName);
        }

      
    }
}